package com.spsa.negocio.servicios;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.spsa.excepciones.EstadoIlegalExcepcion;
import com.spsa.excepciones.GuardarDatosException;
import com.spsa.excepciones.RecuperarDatosException;
import com.spsa.excepciones.ServicioException;
import com.spsa.negocio.utilidades.SingletonDatos;
import com.spsa.persistencia.dao.EstadoInterfazDao;
import com.spsa.persistencia.entidades.EstadoInterfaz;
import com.spsa.persistencia.entidades.Interfaz;
import com.spsa.persistencia.entidades.Tienda;

@Stateless
public class ServicioEstadosTiendas {

	static final Logger logger = LogManager.getLogger(ServicioEstadosTiendas.class.getName());

	@EJB
	private EstadoInterfazDao estadoInterfazDao;
	@EJB
	private SingletonDatos singletonDatos;

	public void actualizarEstadoDeInterfaz(EstadoInterfaz estadoInterfaz) throws ServicioException {
		try {
			String descripcionInterfaz = estadoInterfaz.getDescripcionInterfaz();
			String codigoTienda = estadoInterfaz.getCodigoTienda();
			
			if(!singletonDatos.existeInterfaz(descripcionInterfaz) ||  
			   !singletonDatos.existeTienda(codigoTienda) ) {
				logger.error("Se encontro un mensaje con tienda o interfaz no valida", estadoInterfaz);
				return;
			}
			if(!singletonDatos.buscarTienda(codigoTienda).getInterfaces().contains(singletonDatos.buscarInterfaz(descripcionInterfaz))) {
				logger.error("Se encontro un mensaje asociado a una interfaz no valida de una tienda", estadoInterfaz);
				return;
			}
			
			EstadoInterfaz estadoEnBD = estadoInterfazDao.buscarSimilar(estadoInterfaz);
			
			if(estadoEnBD == null) 
				estadoInterfazDao.guardarOrActualizar(estadoInterfaz);
			
			else {
				estadoEnBD.setCantidadArchivos(estadoInterfaz.getCantidadArchivos());
				estadoEnBD.setCondicion(estadoInterfaz.getCondicion());
				estadoInterfazDao.guardarOrActualizar(estadoEnBD);
			}
		}
		catch(EstadoIlegalExcepcion e) {
			throw new ServicioException("No se encontro informacion sobre la tienda o la interfaz");
		}
		catch(RecuperarDatosException e) {
			throw new ServicioException("No se pudo verificar si el mensaje es repetido");
		}
		catch(GuardarDatosException e) {
			throw new ServicioException("No se pudo procesar el mensaje");
		}
	}

	public int obtenerCantidadTiendasRojo(List<EstadoInterfaz> estados) {
		int numeroTiendasRojo = 0;
		
		for(int i = 0; i < estados.size(); i ++) {
			if(singletonDatos.tiendaEstaActiva(estados.get(i).getCodigoTienda()) && estados.get(i).getCondicion() == 1)
				numeroTiendasRojo ++;
		}
		
		return numeroTiendasRojo;
	}
	
	public int obtenerCantidadTiendasVerde(List<EstadoInterfaz> estados) {
		int numeroTiendasRojo = 0;
		
		for(int i = 0; i < estados.size(); i ++) {
			if(singletonDatos.tiendaEstaActiva(estados.get(i).getCodigoTienda()) && estados.get(i).getCondicion() == 2)
				numeroTiendasRojo ++;
		}
		
		return numeroTiendasRojo;
	}
	
	public int obtenerCantidadTiendasBlanco(List<EstadoInterfaz> estados) {
		int numeroTiendasRojo = 0;
		
		for(int i = 0; i < estados.size(); i ++) {
			if(singletonDatos.tiendaEstaActiva(estados.get(i).getCodigoTienda()) && estados.get(i).getCondicion() == 3)
				numeroTiendasRojo ++;
		}
		
		return numeroTiendasRojo;
	}
	
	public List<EstadoInterfaz> listarPorInterfaz(Interfaz interfaz) throws ServicioException {
		try {
			EstadoInterfaz estadoInterfaz;
			List<Tienda> tiendas = singletonDatos.getTiendas();
			List<EstadoInterfaz> estados = new ArrayList<EstadoInterfaz>(estadoInterfazDao.listarPorInterfaz(interfaz));

			for (int i = 0; i < tiendas.size(); i++) {
				if (existeEstadoParaLaTienda(tiendas.get(i), estados))
					continue;
				else {
					if(tiendas.get(i).getInterfaces().contains(interfaz))
						estadoInterfaz = crearEstadoInterfazDefecto(tiendas.get(i), interfaz, 1);
					else
						estadoInterfaz = crearEstadoInterfazDefecto(tiendas.get(i), interfaz, 3);

					estados.add(estadoInterfaz);
				}
			}

			ordenarEstados(estados);
			return estados;
		} catch (RecuperarDatosException e) {
			throw new ServicioException("No se pudo recuperar los estados de las tiendas de la interfaz "
					+ interfaz.getDescripcion());
		}
	}

	private EstadoInterfaz crearEstadoInterfazDefecto(Tienda tienda, Interfaz interfaz, int condicion) {
		EstadoInterfaz estadoInterfaz = new EstadoInterfaz();
		estadoInterfaz.setCodigoTienda(tienda.getCodigo());
		estadoInterfaz.setDescripcionInterfaz(interfaz.getDescripcion());
		estadoInterfaz.setCondicion(condicion);

		return estadoInterfaz;
	}

	private void ordenarEstados(List<EstadoInterfaz> estados) {
		Collections.sort(estados, new Comparator<EstadoInterfaz>() {

			@Override
			public int compare(EstadoInterfaz estadoInterfaz1, EstadoInterfaz estadoInterfaz2) {
				int peso1 = estadoInterfaz1.getCondicion();
				int peso2 = estadoInterfaz2.getCondicion();

				return peso1 - peso2;
			}

		});
	}

	private boolean existeEstadoParaLaTienda(Tienda tienda, List<EstadoInterfaz> estados) {
		for (int i = 0; i < estados.size(); i++) {
			if (estados.get(i).getCodigoTienda().equals(tienda.getCodigo()))
				return true;
		}

		return false;
	}

}
